home *** CD-ROM | disk | FTP | other *** search
/ MacFormat 1999 April / macformat-075.iso / Shareware Plus / Applications / Alpha / Tcl / Modes / javaMode.tcl < prev    next >
Encoding:
Text File  |  1999-01-19  |  10.0 KB  |  308 lines  |  [TEXT/ALFA]

  1. # (install)
  2.  
  3. alpha::mode Java 1.09 javaMenu {*.java *.j} {
  4.     javaMenu electricBraces electricSemicolon electricReturn
  5. } {
  6.     addMenu javaMenu "•140" Java
  7. }
  8.  
  9. array set javacompilerAppSignatures {
  10.     Suncompiler Javc
  11. }
  12. array set javacompilerAppScripts {
  13.     Suncompiler {
  14.     {sendOpenEvent -n $quotedSig $filename}
  15.     }
  16. }
  17.  
  18. # required for use of C++::correctIndentation
  19. newPref f useFasterButWorseIndentation 0 Java
  20. newPref v indentComments "code 0" Java "" indentationTypes varitem
  21. newPref v indentC++Comments "code 0" Java "" indentationTypes varitem
  22.  
  23. newPref    f elecColon {1} Java
  24. newPref    v leftFillColumn {3} Java
  25. newPref    v prefixString {//} Java 
  26. newPref    f wordWrap {0} Java
  27. newPref    v funcExpr {^[^ \t\(#\r/@].*\(.*\)$} Java
  28. newPref    v parseExpr {\b([_:\w]+)\s*\(} Java
  29. newPref v wordBreak {[\w_]+} Java
  30. newPref v wordBreakPreface {[^_\w]} Java
  31. newPref    f autoMark    0 Java
  32. # To synchronise Alpha's value for your java class path with the current
  33. # value in your system environment each time Alpha starts up, click this 
  34. # box||To let Alpha maintain its own value for your classpath independent
  35. # of the systemwide value, click this box.
  36. newPref    f classPathSynchroniseWithEnv    1 Java
  37. # Your Java class path.
  38. newPref v classSearchPath "" Java
  39. newPref    v stringColor    green Java
  40. newPref    v commentColor    red     Java
  41. newPref    v keywordColor    blue Java
  42. newPref f includeMenu 1 Java
  43. newPref variable showJavacompilerLog 1 Java "" \
  44.   [list "Never" "Only after error" "Always"] index
  45.  
  46. regModeKeywords     -e {//} -b {/*} {*/} -c $JavamodeVars(commentColor) -k    $JavamodeVars(keywordColor)  -s    $JavamodeVars(stringColor) Java    {
  47.     abstract boolean break byte byvalue case catch char class const 
  48.     continue default do double else extends false final finally float for 
  49.     goto if implements import instanceof int interface long native new 
  50.     null package private protected public return short static super switch 
  51.     synchronized this throw throws transient true try void while future 
  52.     generic inner outer operator rest var volatile
  53. }
  54.  
  55. proc javaMenu {} {}
  56.  
  57. if {$JavamodeVars(classPathSynchroniseWithEnv)} {
  58.     if {[info exists env(CLASSPATH)]} {
  59.     set JavamodeVars(classSearchPath) [split $env(CLASSPATH) ";"]
  60.     }
  61. }
  62.  
  63. ## 
  64.  # -------------------------------------------------------------------------
  65.  # 
  66.  # "menu::buildjavaMenu" --
  67.  # 
  68.  #  Use a build proc so we can add things on the fly.
  69.  # -------------------------------------------------------------------------
  70.  ##
  71. proc Java::buildMenu {} {
  72.     global javaMenu
  73.     set ma {
  74.     "/S<U<OswitchToCompiler"
  75.     "(-"
  76.     "/K<U<OcompileFile"
  77.     "(-"
  78.     "/V<U<OviewApplet"
  79.     "//<BnewJavadocComment"
  80.     }
  81.     return [list build $ma Java::MenuProc "" $javaMenu]
  82. }
  83. menu::buildProc javaMenu Java::buildMenu
  84.  
  85. set Java::commentCharacters(Paragraph) [list "/**" " */" " * "]
  86.  
  87. # If this package exists, add the headers menu
  88. if {[alpha::package exists searchPaths]} {
  89.     menu::buildProc javaSearchPath {mode::rebuildSearchPathMenu javaSearchPath}
  90.     menu::insert javaMenu submenu end javaSearchPath
  91. }
  92.  
  93. menu::buildSome javaMenu
  94.  
  95. proc Java::MenuProc {menu item} {
  96.     eval Java::$item
  97. }
  98.  
  99. proc Java::correctIndentation {args} {
  100.     uplevel 1 C++::correctIndentation $args
  101. }
  102. proc Java::indentLine {args} {
  103.     uplevel 1 C++::indentLine $args
  104. }
  105.  
  106. proc Java::newJavadocComment {} {
  107.     elec::Insertion "/**\r * •comment body•\r */\r••"
  108. }
  109.  
  110. # Launches Java Compiler
  111. proc Java::switchToCompiler {} {
  112.     global javacompilerSig
  113.     app::launchAnyOfThese Javc javacompilerSig "Please locate the Java compiler:"
  114.     switchTo '$javacompilerSig'
  115. }
  116.  
  117. # Sends the window to the compiler.
  118. proc Java::compileFile {} {
  119.     global showJavacompilerLog classSearchPath
  120.     set path [stripNameCount [win::Current]]
  121.  
  122.     if {[winDirty]} {
  123.     case [askyesno -c "Save '[file tail $path]'?"] in {
  124.         "yes" {
  125.         save
  126.         # Get path again, in case it was Untitled before.
  127.         set path [stripNameCount [win::Current]]
  128.         }
  129.         "no" {
  130.         if {![file exists $path]} {
  131.             alertnote "Can't send window to compiler."
  132.             return
  133.         }
  134.         }
  135.         "cancel" {return}
  136.     }
  137.     }
  138.     app::runScript javacompiler "Java compiler" \
  139.       $path 0 $showJavacompilerLog "-classpath [join $classSearchPath {;}]"
  140. }
  141.  
  142. # Opens a HTML file corresponding to a java file in the Applet Viewer.
  143. # If there is a file some_applet.html in the same folder as some_applet.java
  144. # it is sent. Otherwise the user is asked to select a HTML file.
  145. # This file is remembered throughout this session with Alpha.
  146. proc Java::viewApplet {} {
  147.     global javaAppletFile javaviewerSig
  148.     set name [stripNameCount [win::Current]]
  149.     set dir [file dirname $name]
  150.     set root [file rootname [file tail $name]]
  151.     set path [file join $dir $root.html]
  152.     if {[info exists javaAppletFile($name)] && [file exists $javaAppletFile($name)]} {
  153.     set path $javaAppletFile($name)
  154.     } elseif {![file exists $path]} {
  155.     set path [getfile "Please locate HTML file for applet."]
  156.     set javaAppletFile($name) $path
  157.     }
  158.     app::launchAnyOfThese [list AppV WARZ] javaviewerSig "Please locate the Applet viewer:"
  159.     sendOpenEvent noReply '$javaviewerSig' $path
  160.     switchTo '$javaviewerSig'
  161. }
  162.  
  163. proc Java::MarkFile {} {
  164.     Java::MarkFile2 1
  165. }
  166.  
  167. proc Java::parseFuncs {} {
  168.     Java::MarkFile2 0
  169. }
  170.  
  171.  
  172. # My version of    Java::MarkFile. First revision, April 1996.
  173. # Jim Menard, jimm@io.com
  174. # Improved by Vince: both start and end position of embedded classes are
  175. # stored, so if we order methods/sub-classes randomly, we still mark 
  176. # things properly.
  177. proc Java::MarkFile2 {marking} {
  178.     # Sorry, but globals are a lot easier than using "upvar" in subroutines
  179.     global markArray
  180.     global classInfo
  181.     
  182.     catch {unset markArray}
  183.     set classInfo ""
  184.     
  185.     # Look for class definitions first
  186.     set markExpr "^\[ \t\]*(\[A-Za-z_\]\[A-Za-z0-9_\]*\[ \t\]+)*class\[ \t\]+\[A-Za-z_\]\[A-Za-z0-9_\]*\[ \t\r\](\[A-Za-z_\]\[A-Za-z0-9_.\]*\[ \t\]+)*\{"
  187.     set wordExpr "class\[ \t\]+(\[A-Za-z_\]\[A-Za-z0-9_\]*)"
  188.     set commands {
  189.     set markArray([concat $word "class"]) $markPos
  190.     # Remember mark    position and name separately so    we can call
  191.     # Java::getClassFromPos() later.
  192.     lappend    classInfo [list $word $markPos $endPos]
  193.     }
  194.     Java::searchAndDestroy $markExpr $wordExpr $commands 0
  195.     
  196.     # The following regular expression is overly restrictive. After the open
  197.     # paren, I disallow semicolons. That avoids finding lines like
  198.     # throw new FooException(arg);
  199.     # which is good, but unfortunately also avoids finding lines like
  200.     # public int foo(arg) // comment with semi;
  201.     #
  202.     # It doesn't find constructors without a "public", "private", or other phrase
  203.     # before the method name since it requires at least one word before the
  204.     # method name. They are special-cased below. I did that so function calls,
  205.     # "if" statements, and the like wouldn't be found.
  206.     set markExpr "^\[ \t\]*(\[A-Za-z_\]\[A-Za-z0-9_\]*(\\\[\\])*\[ \t\]+)+\[A-Za-z_\]\[A-Za-z0-9_\]*\[ \t\r\]*\\(\[^;\]+$"
  207.     set wordExpr "(\[A-Za-z_\]\[A-Za-z0-9_\]*)\[ \t\]*\\("
  208.     set commands {
  209.     if {$className == $word} {
  210.         set markArray([concat $className "constructor"]) $markPos
  211.     } else {
  212.         set markArray(${className}::$word) $markPos
  213.     }
  214.     }
  215.     Java::searchAndDestroy $markExpr $wordExpr $commands 1
  216.     
  217.     # One more time; let's go back for constructors    with no    modifiers.
  218.     set markExpr "^\[ \t\]*\[A-Za-z\]\[A-Za-z0-9_\]*\[ \t\r\]*\\(\[^;\]+$"
  219.     set wordExpr "(\[A-Za-z\]\[A-Za-z0-9_\]*)\[ \t\]*\\("
  220.     set commands {
  221.     if {$className == $word} {
  222.         set markArray([concat $className "constructor"]) [lineStart [expr $start - 1]]
  223.     }
  224.     }
  225.     Java::searchAndDestroy $markExpr $wordExpr $commands 1
  226.     
  227.     if {[info exists markArray]} {
  228.     foreach    f [lsort -ignore [array    names markArray]] {
  229.         set next [nextLineStart $markArray($f)]
  230.         
  231.         if {[regexp {.*(::if)$} $f] == 0} {
  232.         if {[string length $f] > 35} { 
  233.             set ff "[string range $f 0 31]..." 
  234.         } else {
  235.             set ff $f
  236.         }
  237.         if {$marking} {
  238.             setNamedMark "$ff" "$markArray($f)" $next $next
  239.         } else {
  240.             lappend parse $ff $next
  241.         }
  242.         }
  243.     }
  244.     }
  245.     if {!$marking} {return $parse}
  246. }
  247.  
  248. # Start    at top of file and find    text that matches markExpr. Clean it up    and
  249. # use wordExpr to find the word    we want. Execute commands.
  250. proc Java::searchAndDestroy {markExpr wordExpr commands needClassName} {
  251.     global markArray
  252.     global classInfo
  253.     if {!$needClassName} {
  254.     set getEnd 0
  255.     }
  256.     
  257.     set pos [minPos]
  258.     while {![catch {search -s -f 1 -r 1 -m 0 -i 0 -- "$markExpr" $pos} res]} {
  259.     set start [lindex $res 0]
  260.     set end    [pos::math [lindex $res 1] + 1]
  261.     if {[pos::compare $end > [maxPos]]} {
  262.         set end [maxPos]
  263.     }
  264.     set thistext [getText $start $end]
  265.     if {$needClassName} {
  266.         set className [Java::getClassFromPos $start $classInfo]
  267.     }
  268.     # regexp doesn't like carriage returns or tabs
  269.     regsub -all "\[\n\r\t\]" $thistext " " thistext
  270.     # If the open paren was    the last character on the line,
  271.     # the selected text included the last carriage return as well.
  272.     # Trim this off    now that it is changed into a space.
  273.     set thistext [string trimright $thistext]
  274.     if {[regexp $wordExpr $thistext    dummy word]} {
  275.         set markPos [lineStart [pos::math $start - 1]]
  276.         if {[info exists getEnd]} {
  277.         if {$getEnd} {
  278.             set endPos [lindex [search -s -f 1 -m 0 -i 0 -- "\{" $markPos] 1]
  279.             set endPos [matchIt "\{" $endPos]
  280.         } else {
  281.             # little efficiency thing: the first class we find, we know
  282.             # extends to the end of the file, so we don't bother doing
  283.             # its 'matchIt' because it is very time-consuming.
  284.             set endPos [maxPos]
  285.             set getEnd 1
  286.         }
  287.         }
  288.         eval $commands
  289.     }
  290.     set pos    $end
  291.     }
  292. }
  293.  
  294. # Given    a file position, find the class    definition in which it resides.
  295. # There's got to be an easier way than passing two separate lists. 
  296. # I tried fooling
  297. # around with markArray(), but don't know Tcl well enough to use it instead.
  298. proc Java::getClassFromPos {pos classInfo} {
  299.     set nClasses [llength $classInfo]
  300.     for {set i [expr {$nClasses - 1}]} {$i >= 0} {incr i -1} {
  301.     set range [lindex $classInfo $i]
  302.     if {[pos::compare [lindex $range 1] <= $pos] && [pos::compare [lindex $range 2] >= $pos]} {
  303.         return [lindex $range 0]
  304.     }
  305.     }
  306.     return ""
  307. }
  308.